local platform = Player:addState("platform")

function platform:enteredState()
	print("entering player state platform")
	self.last_facing = "right"
	self.facing = "right"	
	self.velocity = 350
	self.accel = 500
	self.min_velocity = 100
	self.max_velocity = 700
	self.jump_velocity = 2000
	self.jump_height = 256
	self.jump_base = 0
	self.jump_times_base = 2
	self.jump_times = 2
	self.jumping = false
	self.crouching = false
	self.cannot_stand = false
	self.touching_x = {}
	self.touching_y = {}
	self.on_ground = false
	self.br_x = self.x+self.width
	self.br_y = self.y+self.height
	self.bl_x = self.x-self.width
	self.bl_y = self.br_y	
	self.punching = false
	self.punched = false
	self.punch_facing = "right"

	function self.punch_anim:once_callback()
		print("self.punch once callback")
		game.player.punching = false
		self:reset()

	end

end

function platform:keypressed(key, isRepeat)
	

	if key == "left" or key == "a" then
		
		self:controls_pressed("walk_left")
		
	end
	if key == "right" or key == "d" then
		
		self:controls_pressed("walk_right")

	end
	if key == "up" or key == "w" then
		self:controls_pressed("jump", isRepeat)
	
	end

	if key == "down" or key == "s" then
		self:controls_pressed("crouch", isRepeat)
	end

	if key == "b" then
		self:controls_pressed("debug")
	end

end

function platform:keyreleased(key)
	if key == "left" or key == "right" or key == "a" or key == "d" then
		
		if key == "left" or key == "a"then
			
			self:controls_released("stop_walk_left")

		elseif key == "right" or key == "d" then
			
			self:controls_released("stop_walk_right")
			
		end
		print("player x: " .. self.x .. " y: " .. self.y)		
	end

	if key == "up" or key == "w" then
		self:controls_released("land")
		
	end

	if key == "down" or key == "s" then
		self:controls_released("stop_crouch")
	end
end

function platform:mousepressed(x, y, button)
	
	if button == "l" then
		print("platform mouse 1 pressed")
		self:controls_pressed("punch")
	end
end

function platform:mousereleased(x, y, button)
end

function platform:controls_pressed(command, isRepeat)
	local commands = {
		["jump"] = function(self) 
			self:jump()
		end,
		["walk_left"] = function(self)
			self:walk("left")
		end,
		["walk_right"] = function(self)
			self:walk("right")	
		end,
		["crouch"] = function(self)
			self:crouch()
		end,
		["punch"] = function(self)
			self:punch()
		end,
		["debug"] = function(self)
			debug.debug()
		end,
	}

	if commands[command] then
		commands[command](self)
	end

end

function platform:controls_released(command)
	local commands = {
		["land"] = function(self)
			self:land()
		end,
		["stop_walk_left"] = function(self)
			self.last_facing = self.facing
			if not love.keyboard.isDown("right") then
				self.walking = false
			end
		end,
		["stop_walk_right"] = function(self)
			self.last_facing = self.facing
			if not love.keyboard.isDown("left") then
				self.walking = false
			end
		end,
		["stop_crouch"] = function(self)
			if not self.cannot_stand then
				self:stand()
			end
		end,

	}

	if commands[command] then
		commands[command](self)
	end
end

function platform:draw()
	if self.punching then
		if self.punch_facing == "right" then
			self.punch_anim:draw(self.x, self.y)
		elseif self.punch_facing == "left" then
			self.punch_anim:draw(self.x, self.y, 0, -1, 1)
		end

		
	else
		if self.jumping then
			--self.touching_x = false
			if self.facing == "right" then
				self.anim:draw_frame(3, self.x, self.y)
			elseif self.facing == "left" then
				self.anim:draw_frame(3, self.x, self.y, 0, -1, 1)
			end
		elseif self.crouching then
			if self.facing == "right" then
				self.anim:draw_frame(5, self.x, self.y)
			elseif self.facing == "left" then
				self.anim:draw_frame(5, self.x+self.width/2, self.y, 0, -1, 1)
			end
		else
			if not self.walking then
				if self.last_facing == "right" then
					self.anim:draw_frame(1, self.x, self.y)
				elseif self.last_facing == "left" then
					self.anim:draw_frame(1, self.x, self.y, 0, -1, 1)
				end
			elseif self.walking == 2 then
				self.anim:draw(self.x,self.y, 0, -1, 1)
			elseif self.walking == 1 then
				self.anim:draw(self.x, self.y, 0, 1, 1)
			end
		end
	end
end

function platform:is_touch_dir(dir)
	local collisions = {}
	--print(dir)

	if dir == "left" or dir == "right" then
		for i = 1, #self.touching_x do
			print("touching dir: " .. self.touching_x[i].dir)
			if self.touching_x[i].dir == dir then
				print("is touching right")
				collisions[#collisions+1] = self.touching_x[i]
			end
		end
	elseif dir == "up" or dir == "down" then		
		for i = 1, #self.touching_y do
			if self.touching_y[i].dir == dir then
				collisions[#collisions+1] = self.touching_y[i]
			end
		end
	end
	if #collisions < 1 then
		return false
	else
		return collisions
	end
	
end

function platform:walk(dir)
	if dir == "right" then
		self.walking = 1
	elseif dir == "left" then
		self.walking = 2
	end
	self.velocity = self.min_velocity	
	self.facing = dir

end

function platform:punch()
	print("punching")
	self.punching = true
	self.walking = false
end

function platform:crouch()
	self.height = 64
	self.crouching = true
end

function platform:stand()
	self.y = self.y - self.height
	self.height = 128
	self.crouching = false
end

function platform:jump()
	self.jump_times = self.jump_times - 1
	self.jumping = true
	self.jump_base = self.br_y
end

function platform:land()
	self.jumping = false
end

function platform:crouch_tester()
	-- all crouch keys hardcoded here atm unfortunately
	if love.keyboard.isDown("down") or love.keyboard.isDown("s") then
		return true
	else
		return false
	end
end

function platform:update(dt)

	if love.mouse.getX() > love.window.getWidth()/2 then
		self.punch_facing = "right"
	else
		self.punch_facing = "left"
	end

	if self.crouching then
		self.height = 64
		if not self.cannot_stand and not self:crouch_tester() then
			self:stand()
		end
	else
		self.height = 128
	end

	self.br_x = self.x+self.width
	self.br_y = self.y+self.height
	self.bl_x = self.x-self.width
	self.bl_y = self.br_y
	if self.facing == "right" then
		self.center_x = self.x+self.width/2
	elseif self.facing == "left" then	
		self.center_x = self.x-self.width/2
	end
	self.center_y = self.y+self.height/2	

	if self.punching then
		self.punch_anim:update(dt)

	end	

	if self.walking then
		self.anim:update(dt)	
		--print(self.facing)
		if self.facing == "right" then
			if not self:is_touch_dir(self.facing) then

				--self.x = self.x + self.velocity/love.timer.getFPS()
				self.x = self.x + self.velocity *dt
				--if self.touching_x == "left" then
				--	self.touching_x = false
				--end
				
			end
			--print("self.x : " .. self.x)
			
		end
		if self.facing == "left" then
			if not self:is_touch_dir(self.facing) then
				
				--self.x = self.x - self.velocity/love.timer.getFPS()
				self.x = self.x - self.velocity * dt
				--if self.touching_x == "right" then
				--	self.touching_x = false
				--end
				
			end
			--print("self.x : " .. self.x)
			
		end

		if self.velocity < self.max_velocity then
			self.velocity = self.velocity + dt*self.accel
		end
		

	end

	if self.jumping  then
		
		if self.br_y < self.jump_base - self.jump_height or self:is_touch_dir("up") then
			self.jumping = false			
		else
			self.y = self.y - self.jump_velocity * dt
		end
	end

	if self:is_touch_dir("down") then		
		self.on_ground = true
		self.jump_times = self.jump_times_base
		--self.jumping = false
		self:remove_colliders_by_dir("down")
	else
		self.on_ground = false
	end
	
	self:remove_colliders_by_dir("right")
	self:remove_colliders_by_dir("left")
	self:remove_colliders_by_dir("up")
	self.cannot_stand = false

end

function platform:check_collision(collider)

	--print("collider x: " .. collider.x .. " collider y: " .. collider.y)
	if collider then
		if self.crouching then
			if collider.br_y > self.br_y-(self.height*2) and self.center_x >= collider.x and self.center_x <= collider.br_x then
				if self.y > collider.y then
					self.cannot_stand = true
					-- send collider handler the opposite direction from where the player is colliding
					-- ie the player is colliding on the top, so the collider is colliding on the bottom
					game:handle_player_collision(collider, "down")			
				end
				
			end
		end

		if self.br_y >= collider.y and self.br_y <= collider.br_y and self.center_x >= collider.x and self.center_x <= collider.br_x then
			if not self.jumping then
				if self.br_y > collider.y then
					self.y = collider.y-self.height
				end
				--print("touching collider")
				-- touching down
				game:handle_player_collision(collider, "up")
				return self:add_collider(collider.x, collider.y, collider.br_x, collider.br_y, "down")		
			end
		elseif self.y <= collider.br_y and self.y > collider.y and self.center_x >= collider.x and self.center_x <= collider.br_x then
			game:handle_player_collision(collider, "down")
			return self:add_collider(collider.x, collider.y, collider.br_x, collider.br_y, "up")
		end 
		-- x,y of player compared to x,y of collider
		if self.br_x >= collider.x and self.br_x <= collider.br_x then
			if collider.y >= self.y and collider.br_y <= self.br_y then
				game:handle_player_collision(collider, "left")
				return self:add_collider(collider.x, collider.y, collider.br_x, collider.br_y, "right")		
				--print("touching right")
				--self.x = collider.x - self.width
			end
		elseif self.bl_x <= collider.br_x and self.bl_x >= collider.x then
			if collider.y >= self.y and collider.br_y <= self.br_y then
				game:handle_player_collision(collider, "right")
				return self:add_collider(collider.x, collider.y, collider.br_x, collider.br_y, "left")		
				--print("touching left")
				--self.x = collider.br_x
			end
		end 

	end

	
end

function platform:match_colliders(x, y, br_x, br_y, dir)
	local colliders = {}
	if dir == "left" or dir == "right" then
		for i = 1, #self.touching_x do
			if x then
				if self.touching_x[i].x == x then
					if self.touching_x[i].y == y then
						if self.touching_x[i].br_x == br_x then
							if self.touching_x[i].br_y == br_y then
								if self.touching_x[i].dir == dir then
									colliders[#colliders+1] = self.touching_x[i]
								end
							end
						end
					end
				end
			end
		end
	end
	return colliders

end

function platform:add_collider(x, y, br_x, br_y, dir)
	local i
	
	if not self:is_touch_dir(dir) then
		
		--print("adding collider at x: " .. x .. " y: " .. y .. " br_x : " .. br_x .. " br_y : " .. br_y)
		if dir == "left" or dir == "right" then
			i = #self.touching_x+1
			self.touching_x[i] = {
			x = x,
			y = y,
			br_x = br_x,
			br_y = br_y,
			dir = dir
			}
			return self.touching_x[i]
		elseif dir == "up" or dir == "down" then
			i = #self.touching_y+1
			self.touching_y[i] = {
			x = x,
			y = y,
			br_x = br_x,
			br_y = br_y,
			dir = dir
			}
			return self.touching_y[i]
		end
	else
		print("duplicate collider")
	end

end

function platform:remove_colliders_by_dir(dir)
	if dir == "left" or dir == "right" then
		for i = #self.touching_x, 1, -1 do
			if self.touching_x[i].dir == dir then
				table.remove(self.touching_x, i)
			end
		end
	elseif dir == "up" or dir == "down" then
		for i = #self.touching_y, 1, -1 do
			if self.touching_y[i].dir == dir then
				table.remove(self.touching_y, i)
			end
		end
	end

end
function platform:exitedState()
	print("exiting player state platform")
end
